import ij.IJ;
import ij.ImagePlus;
import ij.gui.PolygonRoi;
import ij.gui.Roi;
import ij.plugin.filter.PlugInFilter;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author wilbur This is a primitive plugin to collect point trajectories
 *         interactively. Trajectories are marked individually using ImageJ's
 *         polyline selection tool. This plugin must be invoked for each
 *         trajectory. It stores the trajectory as a property of the
 *         corresponding window. Each invocation of this plugin adds a new
 *         trajectory. Use the other plugin "Trajectory_ListAll" to get a
 *         listing of the current trajectories. Use "Trajectory_ClearAll" to
 *         delete all trajectories.
 */
public class Trajectory_Add implements PlugInFilter {

	static boolean verbose = true;

	ImagePlus origImage = null;
	String origTitle = null;
	Random rg = new Random();

	public int setup(String arg, ImagePlus im) {
		origImage = im;
		origTitle = im.getTitle();
		return DOES_RGB;
	}

	public void run(ImageProcessor ip) {
		ColorProcessor cp = (ColorProcessor) ip;
		Roi r = origImage.getRoi();
		if (r != null && r instanceof PolygonRoi) {
			Point[] trajectory = makeTrajectory((PolygonRoi) r);
			addTrajectory(trajectory);
			drawTrajectory(trajectory, cp);
			origImage.killRoi();
			origImage.updateAndDraw();
		} else
			IJ.error("No trajectory (polyline) selected!");
	}

	Point[] makeTrajectory(PolygonRoi poly) {
		Rectangle rect = poly.getBounds();
		int xOff = rect.x;
		int yOff = rect.y;
		int[] xcoords = poly.getXCoordinates();
		int[] ycoords = poly.getYCoordinates();
		int n = poly.getNCoordinates();
		Point[] points = new Point[n];
		for (int k = 0; k < n; k++) {
			points[k] = new Point(xOff + xcoords[k], yOff + ycoords[k]);
		}
		return points;
	}

	@SuppressWarnings("unchecked")
	void addTrajectory(Point[] trajectory) {
		List<Point[]> trajList = (List<Point[]>) origImage
				.getProperty(TrajectoryUtils.PROPKEY);
		if (trajList == null) {
			trajList = new ArrayList<Point[]>();
		}
		trajList.add(trajectory);
		origImage.setProperty(TrajectoryUtils.PROPKEY, trajList);
		IJ.log("Added trajectory " + trajList.size());
	}

	void drawTrajectory(Point[] trajectory, ColorProcessor ip) {
		Color c = randomColor();
		ip.setColor(c);
		Point p = trajectory[0];
		ip.moveTo(p.x, p.y);
		for (int k = 1; k < trajectory.length; k++) {
			p = trajectory[k];
			ip.lineTo(p.x, p.y);
		}

		for (int k = 0; k < trajectory.length; k++) {
			p = trajectory[k];
			TrajectoryUtils.drawSquare(p, ip, 2);
		}
	}

	Color randomColor() {
		float hue = rg.nextFloat();
		float sat = 1.0f;
		float val = 0.75f;
		return new Color(Color.HSBtoRGB(hue, sat, val));
	}

}
